from fastapi import APIRouter, HTTPException, Depends, status, Query, Security
from fastapi.security import HTTPAuthorizationCredentials
from sqlalchemy.orm import Session
from typing import List
from datetime import datetime

from database.database import User, Role, Permission, RolePermission
from database.database_function import get_db
from api.auth import (
    authenticate_user, create_access_token, get_password_hash,
    get_current_active_user, get_user_permissions, require_permission,
    save_user_token, revoke_user_token, security
)
from api.schemas.auth import (
    UserRegister, UserLogin, TokenResponse, UserResponse,
    UserUpdate, PasswordChange, UserListResponse, RoleResponse,
    PermissionResponse, UserCreateByAdmin, UserUpdateByAdmin
)

router = APIRouter()


@router.post("/register", response_model=TokenResponse, summary="用户注册")
async def register(user_data: UserRegister, db: Session = Depends(get_db)):
    """用户注册"""
    # 检查用户名是否已存在
    existing_user = db.query(User).filter(User.username == user_data.username).first()
    if existing_user:
        raise HTTPException(status_code=400, detail="用户名已存在")
    
    # 检查邮箱是否已存在
    existing_email = db.query(User).filter(User.email == user_data.email).first()
    if existing_email:
        raise HTTPException(status_code=400, detail="邮箱已被注册")
    
    # 创建新用户
    hashed_password = get_password_hash(user_data.password)
    new_user = User(
        username=user_data.username,
        email=user_data.email,
        password_hash=hashed_password,
        role_id=2  # 默认为普通用户
    )
    
    db.add(new_user)
    db.commit()
    db.refresh(new_user)
    
    # 创建访问令牌
    token, expires_at = create_access_token(data={"sub": str(new_user.user_id)})
    save_user_token(db, new_user.user_id, token, expires_at)
    
    # 获取用户权限
    permissions = get_user_permissions(db, new_user)
    
    # 获取角色信息
    role = db.query(Role).filter(Role.role_id == new_user.role_id).first()
    
    return TokenResponse(
        access_token=token,
        expires_in=60 * 60 * 24 * 7,  # 7天，单位秒
        user=UserResponse(
            user_id=new_user.user_id,
            username=new_user.username,
            email=new_user.email,
            role_name=role.role_name,
            is_active=new_user.is_active,
            created_time=new_user.created_time,
            last_login_time=new_user.last_login_time,
            permissions=permissions
        )
    )


@router.post("/login", response_model=TokenResponse, summary="用户登录")
async def login(user_data: UserLogin, db: Session = Depends(get_db)):
    """用户登录"""
    user = authenticate_user(db, user_data.username, user_data.password)
    if not user:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="用户名或密码错误",
            headers={"WWW-Authenticate": "Bearer"},
        )
    
    # 更新最后登录时间
    user.last_login_time = datetime.utcnow()
    db.commit()
    
    # 创建访问令牌
    token, expires_at = create_access_token(data={"sub": str(user.user_id)})
    save_user_token(db, user.user_id, token, expires_at)
    
    # 获取用户权限
    permissions = get_user_permissions(db, user)
    
    # 获取角色信息
    role = db.query(Role).filter(Role.role_id == user.role_id).first()
    
    return TokenResponse(
        access_token=token,
        expires_in=60 * 60 * 24 * 7,  # 7天，单位秒
        user=UserResponse(
            user_id=user.user_id,
            username=user.username,
            email=user.email,
            role_name=role.role_name,
            is_active=user.is_active,
            created_time=user.created_time,
            last_login_time=user.last_login_time,
            permissions=permissions
        )
    )


@router.post("/logout", summary="用户登出")
async def logout(
    credentials: HTTPAuthorizationCredentials = Depends(security),
    db: Session = Depends(get_db)
):
    """用户登出"""
    if credentials:
        revoke_user_token(db, credentials.credentials)
    return {"message": "登出成功"}


@router.get(
    "/me", 
    response_model=UserResponse, 
    summary="获取当前用户信息",
    dependencies=[Depends(get_current_active_user)]
)
async def get_current_user_info(
    current_user: User = Depends(get_current_active_user),
    db: Session = Depends(get_db)
):
    """获取当前用户信息"""
    permissions = get_user_permissions(db, current_user)
    role = db.query(Role).filter(Role.role_id == current_user.role_id).first()
    
    return UserResponse(
        user_id=current_user.user_id,
        username=current_user.username,
        email=current_user.email,
        role_name=role.role_name,
        is_active=current_user.is_active,
        created_time=current_user.created_time,
        last_login_time=current_user.last_login_time,
        permissions=permissions
    )


@router.put("/me", response_model=UserResponse, summary="更新当前用户信息")
async def update_current_user(
    user_update: UserUpdate,
    current_user: User = Depends(get_current_active_user),
    db: Session = Depends(get_db)
):
    """更新当前用户信息"""
    if user_update.email is not None:
        # 检查邮箱是否已被其他用户使用
        existing_email = db.query(User).filter(
            User.email == user_update.email,
            User.user_id != current_user.user_id
        ).first()
        if existing_email:
            raise HTTPException(status_code=400, detail="邮箱已被其他用户使用")
        
        current_user.email = user_update.email
    
    current_user.updated_time = datetime.utcnow()
    db.commit()
    db.refresh(current_user)
    
    permissions = get_user_permissions(db, current_user)
    role = db.query(Role).filter(Role.role_id == current_user.role_id).first()
    
    return UserResponse(
        user_id=current_user.user_id,
        username=current_user.username,
        email=current_user.email,
        role_name=role.role_name,
        is_active=current_user.is_active,
        created_time=current_user.created_time,
        last_login_time=current_user.last_login_time,
        permissions=permissions
    )


@router.put("/me/password", summary="修改密码")
async def change_password(
    password_data: PasswordChange,
    current_user: User = Depends(get_current_active_user),
    db: Session = Depends(get_db)
):
    """修改密码"""
    from api.auth import verify_password
    
    # 验证旧密码
    if not verify_password(password_data.old_password, current_user.password_hash):
        raise HTTPException(status_code=400, detail="旧密码错误")
    
    # 更新密码
    current_user.password_hash = get_password_hash(password_data.new_password)
    current_user.updated_time = datetime.utcnow()
    db.commit()
    
    return {"message": "密码修改成功"}


# 管理员相关接口
@router.get("/users", response_model=UserListResponse, summary="获取用户列表（管理员）")
async def get_users(
    page: int = Query(1, ge=1, description="页码"),
    page_size: int = Query(10, ge=1, le=100, description="每页数量"),
    current_user: User = Depends(require_permission("user_management")),
    db: Session = Depends(get_db)
):
    """获取用户列表（管理员权限）"""
    offset = (page - 1) * page_size
    
    users_query = db.query(User).join(Role).order_by(User.created_time.desc())
    total = users_query.count()
    users = users_query.offset(offset).limit(page_size).all()
    
    user_responses = []
    for user in users:
        permissions = get_user_permissions(db, user)
        role = db.query(Role).filter(Role.role_id == user.role_id).first()
        
        user_responses.append(UserResponse(
            user_id=user.user_id,
            username=user.username,
            email=user.email,
            role_name=role.role_name,
            is_active=user.is_active,
            created_time=user.created_time,
            last_login_time=user.last_login_time,
            permissions=permissions
        ))
    
    return UserListResponse(
        users=user_responses,
        total=total,
        page=page,
        page_size=page_size
    )


@router.post("/users", response_model=UserResponse, summary="创建用户（管理员）")
async def create_user(
    user_data: UserCreateByAdmin,
    current_user: User = Depends(require_permission("user_management")),
    db: Session = Depends(get_db)
):
    """创建用户（管理员权限）"""
    # 检查用户名是否已存在
    existing_user = db.query(User).filter(User.username == user_data.username).first()
    if existing_user:
        raise HTTPException(status_code=400, detail="用户名已存在")
    
    # 检查邮箱是否已存在
    existing_email = db.query(User).filter(User.email == user_data.email).first()
    if existing_email:
        raise HTTPException(status_code=400, detail="邮箱已被注册")
    
    # 检查角色是否存在
    role = db.query(Role).filter(Role.role_id == user_data.role_id).first()
    if not role:
        raise HTTPException(status_code=400, detail="角色不存在")
    
    # 创建新用户
    hashed_password = get_password_hash(user_data.password)
    new_user = User(
        username=user_data.username,
        email=user_data.email,
        password_hash=hashed_password,
        role_id=user_data.role_id
    )
    
    db.add(new_user)
    db.commit()
    db.refresh(new_user)
    
    permissions = get_user_permissions(db, new_user)
    
    return UserResponse(
        user_id=new_user.user_id,
        username=new_user.username,
        email=new_user.email,
        role_name=role.role_name,
        is_active=new_user.is_active,
        created_time=new_user.created_time,
        last_login_time=new_user.last_login_time,
        permissions=permissions
    )


@router.put("/users/{user_id}", response_model=UserResponse, summary="更新用户（管理员）")
async def update_user(
    user_id: int,
    user_update: UserUpdateByAdmin,
    current_user: User = Depends(require_permission("user_management")),
    db: Session = Depends(get_db)
):
    """更新用户（管理员权限）"""
    user = db.query(User).filter(User.user_id == user_id).first()
    if not user:
        raise HTTPException(status_code=404, detail="用户不存在")
    
    if user_update.email is not None:
        # 检查邮箱是否已被其他用户使用
        existing_email = db.query(User).filter(
            User.email == user_update.email,
            User.user_id != user_id
        ).first()
        if existing_email:
            raise HTTPException(status_code=400, detail="邮箱已被其他用户使用")
        user.email = user_update.email
    
    if user_update.role_id is not None:
        # 检查角色是否存在
        role = db.query(Role).filter(Role.role_id == user_update.role_id).first()
        if not role:
            raise HTTPException(status_code=400, detail="角色不存在")
        user.role_id = user_update.role_id
    
    if user_update.is_active is not None:
        user.is_active = user_update.is_active
    
    user.updated_time = datetime.utcnow()
    db.commit()
    db.refresh(user)
    
    permissions = get_user_permissions(db, user)
    role = db.query(Role).filter(Role.role_id == user.role_id).first()
    
    return UserResponse(
        user_id=user.user_id,
        username=user.username,
        email=user.email,
        role_name=role.role_name,
        is_active=user.is_active,
        created_time=user.created_time,
        last_login_time=user.last_login_time,
        permissions=permissions
    )


@router.delete("/users/{user_id}", summary="删除用户（管理员）")
async def delete_user(
    user_id: int,
    current_user: User = Depends(require_permission("user_management")),
    db: Session = Depends(get_db)
):
    """删除用户（管理员权限）"""
    if user_id == current_user.user_id:
        raise HTTPException(status_code=400, detail="不能删除自己的账户")
    
    user = db.query(User).filter(User.user_id == user_id).first()
    if not user:
        raise HTTPException(status_code=404, detail="用户不存在")
    
    db.delete(user)
    db.commit()
    
    return {"message": "用户删除成功"}


@router.get("/roles", response_model=List[RoleResponse], summary="获取角色列表")
async def get_roles(
    current_user: User = Depends(require_permission("user_management")),
    db: Session = Depends(get_db)
):
    """获取角色列表"""
    roles = db.query(Role).order_by(Role.role_id).all()
    return [RoleResponse.from_orm(role) for role in roles]


@router.get("/permissions", response_model=List[PermissionResponse], summary="获取权限列表")
async def get_permissions(
    current_user: User = Depends(require_permission("user_management")),
    db: Session = Depends(get_db)
):
    """获取权限列表"""
    permissions = db.query(Permission).order_by(Permission.permission_id).all()
    return [PermissionResponse.from_orm(permission) for permission in permissions]


@router.post("/roles", response_model=RoleResponse, summary="创建角色")
async def create_role(
    role_data: dict,
    current_user: User = Depends(require_permission("user_management")),
    db: Session = Depends(get_db)
):
    """创建角色"""
    # 检查角色名是否已存在
    existing_role = db.query(Role).filter(Role.role_name == role_data.get("role_name")).first()
    if existing_role:
        raise HTTPException(status_code=400, detail="角色名已存在")
    
    new_role = Role(
        role_name=role_data.get("role_name"),
        role_description=role_data.get("role_description")
    )
    
    db.add(new_role)
    db.commit()
    db.refresh(new_role)
    
    # 处理权限分配
    permission_ids = role_data.get("permission_ids", [])
    for permission_id in permission_ids:
        # 检查权限是否存在
        permission = db.query(Permission).filter(Permission.permission_id == permission_id).first()
        if permission:
            role_permission = RolePermission(
                role_id=new_role.role_id,
                permission_id=permission_id
            )
            db.add(role_permission)
    
    db.commit()
    
    return RoleResponse.from_orm(new_role)


@router.put("/roles/{role_id}", response_model=RoleResponse, summary="更新角色")
async def update_role(
    role_id: int,
    role_data: dict,
    current_user: User = Depends(require_permission("user_management")),
    db: Session = Depends(get_db)
):
    """更新角色"""
    role = db.query(Role).filter(Role.role_id == role_id).first()
    if not role:
        raise HTTPException(status_code=404, detail="角色不存在")
    
    # 检查角色名是否已被其他角色使用
    if role_data.get("role_name") and role_data.get("role_name") != role.role_name:
        existing_role = db.query(Role).filter(Role.role_name == role_data.get("role_name")).first()
        if existing_role:
            raise HTTPException(status_code=400, detail="角色名已存在")
    
    # 更新角色信息
    if role_data.get("role_name"):
        role.role_name = role_data.get("role_name")
    if role_data.get("role_description"):
        role.role_description = role_data.get("role_description")
    
    # 更新权限分配
    if "permission_ids" in role_data:
        # 删除现有的角色-权限关联
        db.query(RolePermission).filter(RolePermission.role_id == role_id).delete()
        
        # 添加新的权限分配
        permission_ids = role_data.get("permission_ids", [])
        for permission_id in permission_ids:
            # 检查权限是否存在
            permission = db.query(Permission).filter(Permission.permission_id == permission_id).first()
            if permission:
                role_permission = RolePermission(
                    role_id=role_id,
                    permission_id=permission_id
                )
                db.add(role_permission)
    
    db.commit()
    db.refresh(role)
    
    return RoleResponse.from_orm(role)


@router.delete("/roles/{role_id}", summary="删除角色")
async def delete_role(
    role_id: int,
    current_user: User = Depends(require_permission("user_management")),
    db: Session = Depends(get_db)
):
    """删除角色"""
    role = db.query(Role).filter(Role.role_id == role_id).first()
    if not role:
        raise HTTPException(status_code=404, detail="角色不存在")
    
    # 检查是否有用户使用该角色
    users_with_role = db.query(User).filter(User.role_id == role_id).count()
    if users_with_role > 0:
        raise HTTPException(status_code=400, detail="该角色正在被用户使用，无法删除")
    
    db.delete(role)
    db.commit()
    
    return {"message": "角色删除成功"}


@router.post("/permissions", response_model=PermissionResponse, summary="创建权限")
async def create_permission(
    permission_data: dict,
    current_user: User = Depends(require_permission("user_management")),
    db: Session = Depends(get_db)
):
    """创建权限"""
    # 检查权限名是否已存在
    existing_permission = db.query(Permission).filter(Permission.permission_name == permission_data.get("permission_name")).first()
    if existing_permission:
        raise HTTPException(status_code=400, detail="权限名已存在")
    
    new_permission = Permission(
        permission_name=permission_data.get("permission_name"),
        permission_description=permission_data.get("permission_description")
    )
    
    db.add(new_permission)
    db.commit()
    db.refresh(new_permission)
    
    return PermissionResponse.from_orm(new_permission)


@router.put("/permissions/{permission_id}", response_model=PermissionResponse, summary="更新权限")
async def update_permission(
    permission_id: int,
    permission_data: dict,
    current_user: User = Depends(require_permission("user_management")),
    db: Session = Depends(get_db)
):
    """更新权限"""
    permission = db.query(Permission).filter(Permission.permission_id == permission_id).first()
    if not permission:
        raise HTTPException(status_code=404, detail="权限不存在")
    
    # 检查权限名是否已被其他权限使用
    if permission_data.get("permission_name") and permission_data.get("permission_name") != permission.permission_name:
        existing_permission = db.query(Permission).filter(Permission.permission_name == permission_data.get("permission_name")).first()
        if existing_permission:
            raise HTTPException(status_code=400, detail="权限名已存在")
    
    # 更新权限信息
    if permission_data.get("permission_name"):
        permission.permission_name = permission_data.get("permission_name")
    if permission_data.get("permission_description"):
        permission.permission_description = permission_data.get("permission_description")
    
    db.commit()
    db.refresh(permission)
    
    return PermissionResponse.from_orm(permission)


@router.delete("/permissions/{permission_id}", summary="删除权限")
async def delete_permission(
    permission_id: int,
    current_user: User = Depends(require_permission("user_management")),
    db: Session = Depends(get_db)
):
    """删除权限"""
    permission = db.query(Permission).filter(Permission.permission_id == permission_id).first()
    if not permission:
        raise HTTPException(status_code=404, detail="权限不存在")
    
    # 检查是否有角色使用该权限
    roles_with_permission = db.query(RolePermission).filter(RolePermission.permission_id == permission_id).count()
    if roles_with_permission > 0:
        raise HTTPException(status_code=400, detail="该权限正在被角色使用，无法删除")
    
    db.delete(permission)
    db.commit()
    
    return {"message": "权限删除成功"}


@router.get("/roles/{role_id}/permissions", response_model=List[PermissionResponse], summary="获取角色的权限")
async def get_role_permissions(
    role_id: int,
    current_user: User = Depends(require_permission("user_management")),
    db: Session = Depends(get_db)
):
    """获取角色的权限列表"""
    role = db.query(Role).filter(Role.role_id == role_id).first()
    if not role:
        raise HTTPException(status_code=404, detail="角色不存在")
    
    # 查询角色的权限
    role_permissions = db.query(Permission).join(
        RolePermission, Permission.permission_id == RolePermission.permission_id
    ).filter(RolePermission.role_id == role_id).all()
    
    return [PermissionResponse.from_orm(permission) for permission in role_permissions] 